<template>
  <el-row class="retrieval">
    <el-col :span="12" class="search-block">
      <el-row class="search-input">
        <el-col :span="20">
          <el-input :placeholder="search_hint_str" v-model="str_to_search" clearable class="input-with-select">
            <el-select v-model="platform_to_search" slot="prepend" style="width: 90px; margin-right: 10px; border-right: 1px solid #DCDFE6;">
              <el-option label="Maven" value="1"></el-option>
              <el-option label="Pypi" value="2"></el-option>
              <el-option label="Euler" value="3"></el-option>
            </el-select>
            <el-select v-model="type_to_search" slot="prepend" style="width: 80px; padding-left: 10px">
              <el-option label="包" value="1"></el-option>
              <el-option v-show="platform_to_search!=='3'" label="项目" value="2"></el-option>
              <el-option label="漏洞" value="3"></el-option>
            </el-select>
          </el-input>
        </el-col>
        <el-col :span="4">
          <el-button type="primary" @click="search_info">搜索</el-button>
        </el-col>
      </el-row>
      <el-row class="search-output" v-loading="is_search_loading">
        <el-scrollbar style="height: 100%">
          <el-row v-if="pkg_list.length===0 && cve_list.length===0 && pjt_list.length===0 && is_search_loading===false">
            <el-empty description="搜索结果为空"></el-empty>
          </el-row>
          <el-row v-else-if="pkg_list.length!==0">
            <el-row v-for="(pkg, index) in pkg_list" class="output-item" :key="index">
              <el-row class="item-name" @click.native="get_pkg_info(pkg.pkg_id)">{{ pkg.pkg_id }}</el-row>
              <el-row class="item-info">{{ pkg.pkg_info }}</el-row>
            </el-row>
          </el-row>
          <el-row v-else-if="cve_list.length!==0">
            <el-row v-for="(cve, index) in cve_list" class="output-item" :key="index">
              <el-row class="item-name" @click.native="get_cve_info(cve.name)">{{ cve.name }}</el-row>
              <el-row class="item-info">{{ brief_descri(cve.description) }}</el-row>
            </el-row>
          </el-row>
          <el-row v-else-if="pjt_list.length!==0">
            <el-row v-for="(pjt, index) in pjt_list" class="output-item" :key="index">
              <el-row class="item-name" @click.native="get_pjt_info(pjt.name, pjt.license)">{{ pjt.name }}</el-row>
              <el-row class="item-info">{{ pjt.license }}</el-row>
            </el-row>
          </el-row>
        </el-scrollbar>
      </el-row>
    </el-col>
    <el-col :span="12" class="info-block">
      <el-tabs v-model="info_type">
        <el-tab-pane label="节点信息" name="1" class="node" v-loading="is_info_loading">
            <el-row v-if="info_to_show==='empty'" class="empty-hint">
              点击左侧节点以显示详细信息
            </el-row>
            <el-row v-if="info_to_show==='pkg'" class="node-info-block">
              <el-scrollbar style="height: 100%">
                <el-row class="text-block">
                  <el-row class="info-name">
                    {{ pkg_info.name }}
                  </el-row>
                  <el-row class="info-subtitle">
                    Release {{ pkg_info.version }}
                  </el-row>
                  <el-row class="info-descri">
                    {{ pkg_info.info }}
                  </el-row>
                </el-row>
                <el-row class="url-block">
                  <el-row class="info-url">
                    <el-col :span="2">
                      <el-image
                          style="height: 26px"
                          :src="require('../../assets/github_logo.png')"
                          fit="fit"
                      >
                      </el-image>
                    </el-col>
                    <el-col class="_url" :span="22" style="line-height: 26px; margin-left: -10px" @click.native="to_url(pkg_info.repo_url)">
                      {{ pkg_info.repo_url }}
                    </el-col>
                  </el-row>
                  <el-row class="info-url">
                    <el-col :span="2">
                      <el-image
                          style="height: 26px"
                          :src="require('../../assets/home_logo.png')"
                          fit="fit"
                      >
                      </el-image>
                    </el-col>
                    <el-col class="_url" :span="22" style="line-height: 26px; margin-left: -10px" @click.native="to_url(pkg_info.homepage)">
                      {{ pkg_info.homepage }}
                    </el-col>
                  </el-row>
                </el-row>
                <el-row class="cve-block" v-if="pkg_cve_list.length!==0">
                  <el-row class="cve-title">
                    Direct vulnerabilities:
                  </el-row>
                  <el-row class="cve-tag-container">
                    <el-tag class="cve-tag" size="small" v-for="(cve, index) in pkg_cve_list" :key="index" @click="to_cve(cve)">{{ cve }}</el-tag>
                  </el-row>
                </el-row>
                <el-row class="version-block" v-if="pkg_version_list.length!==0">
                  <el-row class="version-title">
                    Included releases ({{ pkg_version_list.length }}) :
                  </el-row>
                  <el-row v-if="more_version===false">
                    <el-row v-for="(version, index) in pkg_version_list_short" class="version-container" :key="index">
                      <span class="version-num" @click="get_pkg_info(version.ID)">{{ version.version }}</span>
                      <span class="version-latest" v-if="version.is_latest===true">LATEST</span>
                    </el-row>
                    <el-row v-if="pkg_version_list.length>5" class="version-opt-container">
                      <span class="version-opt" @click="show_more_versions">See all {{ pkg_version_list.length }} releases...</span>
                    </el-row>
                  </el-row>
                  <el-row v-else>
                    <el-row v-for="(version, index) in pkg_version_list" class="version-container" :key="index">
                      <span class="version-num" @click="get_pkg_info(version.ID)">{{ version.version }}</span>
                      <span class="version-latest" v-if="version.is_latest===true">LATEST</span>
                    </el-row>
                    <el-row v-if="pkg_version_list.length>5" class="version-opt-container">
                      <span class="version-opt" @click="hide_more_versions">Hide</span>
                    </el-row>
                  </el-row>
                </el-row>
              </el-scrollbar>
            </el-row>
            <el-row v-if="info_to_show==='cve'" class="node-info-block">
              <el-scrollbar style="height: 100%">
                <el-row class="text-block">
                  <el-row class="info-name">
                    {{ cve_info.name }}
                  </el-row>
                  <el-row class="info-subtitle">
                    Publish time: {{ cve_info.publish_time }}
                  </el-row>
                  <el-row class="info-descri">
                    {{ cve_info.description }}
                  </el-row>
                </el-row>
                <el-row class="url-block">
                  <el-row class="info-url">
                    <el-col :span="2">
                      <el-image
                          style="height: 26px"
                          :src="require('../../assets/home_logo.png')"
                          fit="fit"
                      >
                      </el-image>
                    </el-col>
                    <el-col class="_url" :span="22" style="line-height: 26px; margin-left: -10px" @click.native="to_cve(cve_info.name)">
                      https://cve.mitre.org
                    </el-col>
                  </el-row>
                </el-row>
              </el-scrollbar>
            </el-row>
            <el-row v-if="info_to_show==='pjt'" class="node-info-block">
            <el-scrollbar style="height: 100%">
              <el-row class="text-block">
                <el-row class="info-name">
                  {{ pjt_info.name }}
                </el-row>
                <el-row class="info-subtitle">
                  {{ pjt_info.license }}
                </el-row>
                <el-row class="info-descri">
                  {{ pjt_info.description }}
                </el-row>
                <el-row class="info-other">
                  <span style="font-weight: bold; margin-right: 5px">Language:</span> {{ pjt_info.language }}
                </el-row>
                <el-row class="info-other">
                  <span style="font-weight: bold; margin-right: 5px">Owner:</span> {{ pjt_info.owner_name }} (Github_id: {{ pjt_info.owner }})
                </el-row>
              </el-row>
              <el-row class="url-block">
                <el-row class="info-url">
                  <el-col :span="2">
                    <el-image
                        style="height: 26px"
                        :src="require('../../assets/home_logo.png')"
                        fit="fit"
                    >
                    </el-image>
                  </el-col>
                  <el-col class="_url" :span="22" style="line-height: 26px; margin-left: -10px" @click.native="to_url(pjt_info.URL)">
                    {{ pjt_info.URL }}
                  </el-col>
                </el-row>
              </el-row>
            </el-scrollbar>
          </el-row>
          </el-tab-pane>
        <el-tab-pane label="拓扑信息" name="2">
          <el-row v-if="info_to_show==='empty'" class="empty-hint">
            点击左侧节点以显示详细信息
          </el-row>
          <el-row v-show="info_to_show!=='empty' && platform_to_show==='1'" ref="viz" id="viz" class="graph-block"></el-row>
          <el-row v-show="info_to_show!=='empty' && platform_to_show==='2'" ref="viz_pypi" id="viz_pypi" class="graph-block"></el-row>
          <el-row v-show="info_to_show!=='empty' && platform_to_show==='3'" ref="viz_euler" id="viz_euler" class="graph-block"></el-row>
          <el-row v-show="info_to_show!=='empty'" class="graph-opt">
            <el-col class="graph-hint" :span="18">
              <el-row class="hint-text">* 悬停以显示节点信息</el-row>
              <el-row class="hint-text">* 点击以显示扩展信息</el-row>
            </el-col>
            <el-col class="graph-btn-container" :span="6">
              <el-button @click="hide_ex_info" class="graph-btn">隐藏扩展信息</el-button>
            </el-col>
          </el-row>
        </el-tab-pane>
      </el-tabs>
    </el-col>
  </el-row>
</template>

<script>
import axios from "axios";
import NeoVis from 'neovis.js/dist/neovis.js';

export default {
  name: "Retrieval",
  props: {
    pkg_to_show: {
      type: String,
      default: "",
    },
    platform: {
      type: String,
      default: "",
    }
  },
  data() {
    return {
      is_search_loading: false,
      is_info_loading: false,
      str_to_search: "",
      type_to_search: "1",
      platform_to_search: "1",
      platform_to_show: "1",    // 缓存搜索点击时的目标搜索平台
      info_type: "1",
      more_version: false,
      pkg_list: [],
      pkg_info: null,
      pkg_cve_list: [],   // 指定版本包的漏洞信息
      pkg_version_list: [],   // 指定版本包的所有版本信息
      cve_list: [],
      cve_info: null,
      pjt_list: [],
      pjt_info: null,
      info_to_show: "empty",
      // 图谱可视化相关
      neovis_labels: {
        Package: {
          caption: 'ID',  // 节点显示的文字对应内容key
          size: "1",  // 用作节点大小的属性名。默认为1
          font: { size: 12, color: '#2c3e50' },  // 字体设置
        },
        Project: {
          caption: 'name',
          size: "1",
          font: { size: 12, color: '#2c3e50' },  // 字体设置
        },
        Vulnerability: {
          caption: 'name',
          size: "1",
          font: { size: 12, color: '#2c3e50' },  // 字体设置
        },
        Developer: {
          caption: 'name',
          size: "1",
          font: { size: 12, color: '#2c3e50' },  // 字体设置
        },
        Repository: {
          caption: 'URL',
          size: "1",
          font: { size: 12, color: '#2c3e50' },  // 字体设置
        },
      },    // neovis的label样式配置
      neovis_relationships: {
        depends_on_project: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        depends_on_pkg: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        buildrequire_pkg: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        include_vul: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        affect_pkg: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        vul_exploit: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        part_of_project: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        develop: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        include_developer: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        store_at: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        include_pkg: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        },
        commit_update_repo: {
          thickness: "1",
          caption: true,
          font: { size: 12, color: '#2c3e50'},
        }
      },    // neovis的relationship样式配置
    }
  },
  methods: {
    search_info: function () {
      this.info_to_show = "empty"
      // 缓存列表结果所属的平台
      this.platform_to_show = this.platform_to_search
      // 输入判断与预处理
      this.pkg_list = this.cve_list = this.pjt_list = []
      let str = this.str_to_search.replace(/(^\s*)|(\s*$)/g, "");
      if (str === "") {
        this.$message.error('搜索内容不能为空')
        return
      }
      // 加载中
      this.is_search_loading = true
      // 发送GET请求
      if (this.type_to_search === "1") {
        axios({
          method: "get",
          params: { name: str, platform: this.platform_to_search },
          url: "http://localhost:8000/search/pkg"
        }).then(res => {
          // console.log(res)
          if (res.status !== 200) {
              this.$message.error('检索Maven包出现未知错误')
          } else {
            this.pkg_list = res.data.data
            // 加载完毕
            this.is_search_loading = false
          }
        })
      }
      else if (this.type_to_search === "2") {
        axios({
          method: "get",
          params: { name: str, platform: this.platform_to_search },
          url: "http://localhost:8000/search/pjt"
        }).then(res => {
          if (res.status !== 200) {
            this.$message.error('检索项目信息出现未知错误')
          } else {
            this.pjt_list = res.data.data
            // 加载完毕
            this.is_search_loading = false
          }
        })
      }
      else if (this.type_to_search === "3") {
        axios({
          method: "get",
          params: { id: str, platform: this.platform_to_search },
          url: "http://localhost:8000/search/cve"
        }).then(res => {
          // console.log(res)
          if (res.status !== 200) {
            this.$message.error('检索漏洞信息出现未知错误')
          } else {
            if (res.data.data !== null) {
              this.cve_list = [res.data.data]
            } else {
              this.cve_list = []
            }
            // 加载完毕
            this.is_search_loading = false
          }
        })
      }
    },
    brief_descri(str) {
      return str.length>=150 ? str.substring(0, 148) + "..." : str
    },
    show_more_versions() {
      this.more_version = true
    },
    hide_more_versions() {
      this.more_version = false
    },
    get_pkg_info: function (pkg_id) {
      this.info_to_show = "pkg"
      this.more_version = false
      this.is_info_loading = true
      // 发送GET请求获取包信息
      axios({
        method: "get",
        params: { pkg_id: pkg_id, platform: this.platform_to_show },
        url: "http://localhost:8000/search/pkg_detail"
      }).then(res => {
        if (res.status !== 200) {
          this.$message.error('获取包详细信息时出现未知错误')
        } else {
          console.log(res.data.data)
          this.pkg_info = res.data.data
          this.pkg_version_list = this.pkg_info.version_list
          this.is_info_loading = false
        }
      })
      // 发送GET请求获取漏洞信息
      axios({
        method: "get",
        params: { pkg_id: pkg_id, platform:this.platform_to_show },
        url: "http://localhost:8000/search/pkg_cve"
      }).then(res => {
        if (res.status !== 200) {
          this.$message.error('获取包CVE信息时出现未知错误')
        } else {
          this.pkg_cve_list = res.data.data
        }
      })
      // 进行数据库查询获取拓扑信息
      if (this.platform_to_show === "1") {
        this.viz.clearNetwork()
        const statement = 'match p = (n:Package{ID:"' + pkg_id + '"})-[r]->() return p'
        this.viz.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "2") {
        this.viz_pypi.clearNetwork()
        const statement = 'match p = (n:Package{ID:"' + pkg_id + '"})-[r]->() return p'
        this.viz_pypi.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "3") {
        this.viz_euler.clearNetwork()
        const statement = 'match p = (n:Package{ID:"' + pkg_id + '"})-[r]->() return p'
        this.viz_euler.updateWithCypher(statement)
      }
    },
    get_cve_info: function (cve_id) {
      this.info_to_show = "cve"
      this.cve_info = this.cve_list[0]
      if (this.platform_to_show === "1") {
        this.viz.clearNetwork()
        const statement = 'match p = (n:Vulnerability{name:"' + cve_id + '"})-[r]->() return p limit 100'
        this.viz.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "2") {
        this.viz_pypi.clearNetwork()
        const statement = 'match p = (n:Vulnerability{CVE_ID:"' + cve_id + '"})-[r]->() return p limit 100'
        this.viz_pypi.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "3") {
        this.viz_euler.clearNetwork()
        const statement = 'match p = (n:Vulnerability{CVE_ID:"' + cve_id + '"})-[r]->() return p limit 100'
        this.viz_euler.updateWithCypher(statement)
      }
    },
    get_pjt_info: function (pjt_name, pjt_license) {
      this.info_to_show = "pjt"
      // 发送GET请求获取项目信息
      axios({
        method: "get",
        params: { name: pjt_name, platform: this.platform_to_show },
        url: "http://localhost:8000/search/pjt_detail"
      }).then(res => {
        if (res.status !== 200) {
          this.$message.error('获取项目详细信息时出现未知错误')
        } else {
          this.pjt_info = res.data.data
          this.pjt_info["license"] = pjt_license
        }
      })
      // 进行数据库查询获取拓扑信息
      if (this.platform_to_show === "1") {
        this.viz.clearNetwork()
        const statement = 'match p = (n:Project{name:"' + pjt_name + '"})-[r]->() return p limit 100'
        this.viz.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "2") {
        this.viz_pypi.clearNetwork()
        const statement = 'match p = (n:Project{name:"' + pjt_name + '"})-[r]->() return p limit 100'
        this.viz_pypi.updateWithCypher(statement)
      }

    },
    to_url: function (url) {
      window.open(url)
    },
    to_cve: function (cve) {
      window.open("https://cve.mitre.org/cgi-bin/cvename.cgi?name=" + cve)
    },
    // 图谱配置初始化
    config_maven_graph: function() {
      let config = {
        container_id: 'viz', // dom元素id
        server_url: 'bolt://211.71.15.39:8687',
        server_user: 'neo4j',
        server_password: 'maven',
        // 节点样式配置
        labels: this.neovis_labels,
        // 关系样式配置
        relationships: this.neovis_relationships,
        // 其他配置
        arrows: true,  // 关系线段是否显示箭头
        hierarchical: false, // 节点显示方式(是否启用分层布局)
        hierarchical_sort_method: 'directed',
        encrypted: 'ENCRYPTION_OFF',
        trust: 'TRUST_ALL_CERTIFICATES',
        initial_cypher: this.pkg_to_show === "" ? "" : 'match p = (n:Package{ID:\"' + this.pkg_to_show + '\"})-[r]->() return p'
      }
      this.viz = new NeoVis(config)
      this.viz.render()
      // 注册点击事件
      this.viz.registerOnEvent('clickNode', this.node_click)
    },
    config_euler_graph: function() {
      let config = {
        container_id: 'viz_euler', // dom元素id
        server_url: 'bolt://211.71.15.39:7687',
        server_user: 'neo4j',
        server_password: 'euler',
        // 节点样式配置
        labels: this.neovis_labels,
        // 关系样式配置
        relationships: this.neovis_relationships,
        // 其他配置
        arrows: true,  // 关系线段是否显示箭头
        hierarchical: false, // 节点显示方式(是否启用分层布局)
        hierarchical_sort_method: 'directed',
        encrypted: 'ENCRYPTION_OFF',
        trust: 'TRUST_ALL_CERTIFICATES',
        initial_cypher: this.pkg_to_show === "" ? "" : 'match p = (n:Package{ID:\"' + this.pkg_to_show + '\"})-[r]->() return p'
      }
      this.viz_euler = new NeoVis(config)
      this.viz_euler.render()
      // 注册点击事件
      this.viz_euler.registerOnEvent('clickNode', this.node_click_euler)
    },
    config_pypi_graph: function() {
      let config = {
        container_id: 'viz_pypi', // dom元素id
        server_url: 'bolt://211.71.15.39:9687',
        server_user: 'neo4j',
        server_password: 'python',
        // 节点样式配置
        labels: this.neovis_labels,
        // 关系样式配置
        relationships: this.neovis_relationships,
        // 其他配置
        arrows: true,  // 关系线段是否显示箭头
        hierarchical: false, // 节点显示方式(是否启用分层布局)
        hierarchical_sort_method: 'directed',
        encrypted: 'ENCRYPTION_OFF',
        trust: 'TRUST_ALL_CERTIFICATES',
        initial_cypher: this.pkg_to_show === "" ? "" : 'match p = (n:Package{ID:\"' + this.pkg_to_show + '\"})-[r]->() return p'
      }
      this.viz_pypi = new NeoVis(config)
      this.viz_pypi.render()
      // 注册点击事件
      this.viz_pypi.registerOnEvent('clickNode', this.node_click_pypi)
    },
    // 图谱点击事件
    node_click: function (node) {
      this.viz._network.off('click')
      const statement ='match p = (n)-[r]->() where id(n)= ' + node.nodeId + ' return p'
      this.viz.updateWithCypher(statement)
    },
    node_click_euler: function (node) {
      this.viz_euler._network.off('click')
      const statement ='match p = (n)-[r]->() where id(n)= ' + node.nodeId + ' return p'
      this.viz_euler.updateWithCypher(statement)
    },
    node_click_pypi: function (node) {
      this.viz_pypi._network.off('click')
      const statement ='match p = (n)-[r]->() where id(n)= ' + node.nodeId + ' return p'
      this.viz_pypi.updateWithCypher(statement)
    },
    hide_ex_info: function () {
      if (this.platform_to_show === "1") {
        this.viz.clearNetwork()
        let statement = ""
        if (this.info_to_show === "pkg") {
          statement = 'match p = (n:Package{ID:"' + this.pkg_info.ID + '"})-[r]->() return p'
        }
        else if (this.info_to_show === "pjt") {
          statement = 'match p = (n:Project{name:"' + this.pjt_info.name + '"})-[r]->() return p limit 100'
        }
        else {
          statement = 'match p = (n:Vulnerability{name:"' + this.cve_info.name + '"})-[r]->() return p limit 100'
        }
        this.viz.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "2") {
        this.viz_pypi.clearNetwork()
        let statement = ""
        if (this.info_to_show === "pkg") {
          statement = 'match p = (n:Package{ID:"' + this.pkg_info.ID + '"})-[r]->() return p'
        }
        else if (this.info_to_show === "pjt") {
          statement = 'match p = (n:Project{name:"' + this.pjt_info.name + '"})-[r]->() return p limit 100 '
        }
        else {
          statement = 'match p = (n:Vulnerability{CVE_ID:"' + this.cve_info.name + '"})-[r]->() return p limit 100'
        }
        this.viz_pypi.updateWithCypher(statement)
      }
      else if (this.platform_to_show === "3") {
        this.viz_euler.clearNetwork()
        let statement = ""
        if (this.info_to_show === "pkg") {
          statement = 'match p = (n:Package{ID:"' + this.pkg_info.ID + '"})-[r]->() return p'
        } else {
          statement = 'match p = (n:Vulnerability{CVE_ID:"' + this.cve_info.name + '"})-[r]->() return p'
        }
        this.viz_euler.updateWithCypher(statement)
      }
    },
  },
  computed: {
    search_hint_str() {
      if (this.type_to_search === "1") {
        return "输入完整包坐标以获得更精确的结果"
      }
      else if (this.type_to_search === "2") {
        return "请输入项目名"
      }
      else if (this.type_to_search === "3") {
        return "请输入准确的CVE-ID"
      }
      else {
        return ""
      }
    },
    pkg_version_list_short() {
      if (this.pkg_version_list.length <= 5) {
        return this.pkg_version_list
      }
      else {
        return this.pkg_version_list.slice(0, 5)
      }
    }
  },
  mounted() {
    // 图谱配置
    this.config_maven_graph()
    this.config_euler_graph()
    this.config_pypi_graph()
    // 初始化pkg
    console.log(this.pkg_to_show)
    if (this.pkg_to_show !== "") {
      // 初始化platform
      if (this.platform==="maven") {
        this.platform_to_show = "1"
      }
      else if (this.platform==="pypi") {
        this.platform_to_show = "2"
      }
      else if (this.platform==="euler") {
        this.platform_to_show = "3"
      }
      this.get_pkg_info(this.pkg_to_show)
    }
  },
}
</script>

<style scoped>
.search-block {
  padding: 0 20px;
  margin-top: 20px;
  height: 630px;
  border-right: gainsboro 1px solid;
}

.search-output {
  margin-top: 30px;
  text-align: left;
  height: 550px;
  overflow-y: auto;
}
.search-output >>> .el-scrollbar__wrap {
  overflow-x: hidden;
}
.output-item {
  margin-bottom: 26px;
  border-left: #2c3e50 2px solid;
  padding: 2px 0 2px 10px
}
.item-name {
  color: #395cc5;
  font-size: 16px;
  font-weight: bold;
}
.item-name:hover {
  cursor: pointer;
  color: #021f7c;
  text-decoration:underline
}
.item-info {
  margin-top: 10px;
  font-size: 14px;
  line-height: 20px;
}

.node-info-block {
  margin-top: 16px;
  text-align: left;
  height: 540px;
  overflow-y: auto;
}
.info-block >>> .el-scrollbar__wrap {
  overflow-x: hidden;
}
.info-block {
  padding: 0 20px 0 30px;
  margin-top: 20px;
  height: 600px;
}
.info-name {
  font-size: 36px;
}
.info-subtitle {
  margin-top: 12px;
  font-size: 24px;
  color: grey;
}
.info-descri {
  margin-top: 12px;
  line-height: 24px;
  padding-right: 12px;
  text-align: justify;
}
.info-other {
  margin-top: 12px;
}
.info-url {
  margin-top: 10px;
}

.cve-title {
  font-weight: bold;
}
.cve-tag-container {
  margin-top: 10px;
}
.cve-tag {
  margin: 0 6px 6px 0;
}
.cve-tag:hover {
  cursor: pointer;
}

.version-title {
  font-weight: bold;
  margin-bottom: 6px;
}
.version-container {
  margin-top: 5px;
}
.version-num {
  color: #395cc5;
  font-size: 15px;
}
.version-num:hover {
  cursor: pointer;
  color: #021f7c;
  text-decoration: underline;
}
.version-latest {
  color: #67C23A;
  font-size: 14px;
  margin-left: 14px;
}
.version-opt-container {
  margin-top: 8px;
}
.version-opt {
  color: #2c3e50;
  font-size: 15px;
}
.version-opt:hover {
  text-decoration: underline;
  cursor: pointer;
}

.text-block {
  padding-bottom: 20px;
}
.url-block {
  padding-top: 10px;
  border-top: gainsboro 1px solid;
  padding-bottom: 16px;
  border-bottom: gainsboro 1px solid;
}
.cve-block {
  padding-top: 20px;
  padding-bottom: 16px;
  border-bottom: gainsboro 1px solid;
}
.version-block {
  padding-top: 20px;
}

.empty-hint {
  color: #909399;
  margin-top: 20px;
  font-size: 14px;
}

.graph-block {
  margin-top: 10px;
  width: 100%;
  height: 500px;
  border-left: #2c3e50 4px solid;
  border-right: rgba(44, 62, 80, 0.05) 1px solid;
  background-color: rgba(44, 62, 80, 0.05);
}
.graph-opt {
  text-align: left;
  margin-top: 10px;
}
.hint-text {
  color: #909399;
  font-size: 14px;
  margin-top: 5px;
}
.graph-btn-container {
  margin-top: 10px;
}
.graph-btn {
  height: 32px;
  line-height: 32px;
  width: 116px;
  padding: 0;
}

._url {
  color: #5192ff;
}
._url:hover {
  color: #2373ff;
  cursor: pointer;
}


.info-block >>> .el-tabs__item.is-active {
 color: #0e90ff;
}
.info-block >>> .el-tabs__item:hover {
color: #0e90ff;
}
.cve-tag-container >>> .el-tag {
  background-color: #fff2f5;
  border-color: #ffdbe2;
  color: crimson;
}
.el-button--primary {
  background-color: #0e90ff;
}
.el-button--primary:hover {
  background-color: #1ea4ff;
}
.graph-opt .el-button:hover {
  color: #0e90ff;
  background-color: #f0f6fa;
  border-color: #d2e4f5;
}
</style>